package com.bolt.core.view.config;

import com.bolt.common.utils.StrUtil;
import com.bolt.core.view.components.*;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.RuleSetBase;
import org.xml.sax.Attributes;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class ViewRuleSet extends RuleSetBase {

    @Override
    public void addRuleInstances(Digester digester) {
        // TODO Auto-generated method stub
        digester.addObjectCreate("page", "com.bolt.core.view.components.PageView", "className");
        digester.addSetProperties("page");
        digester.addSetNext("page", "addPage");

        digester.addRule("page/form", new createForm());
        digester.addSetProperties("page/form");
        digester.addSetNext("page/form", "addForm", "com.bolt.core.view.components.Form");


        //处理验证配置
        digester.addObjectCreate("page/form/validate", "com.bolt.core.view.components.ValidatorRule", "className");
        digester.addRule("page/form/validate", new setValidateRule());
        digester.addSetNext("page/form/validate", "addValidators", "com.bolt.core.view.components.ValidatorRule");

        digester.addSetNext("page/form", "addForm", "com.bolt.core.view.components.Form");

        digester.addRule("page/form/formItem", new createFormItem());
        digester.addSetProperties("page/form/formItem");
        digester.addRule("page/form/formItem/attribute", new addItemAttributeRule());
        digester.addRule("page/form/formItem/itemValue", new setItemValue());
        digester.addSetNext("page/form/formItem", "addFormItems", "com.bolt.core.view.components.FormItem");


        digester.addObjectCreate("page/form/combination", "com.bolt.core.view.components.CombinationFormItem");
        digester.addSetProperties("page/form/combination");
        digester.addRule("page/form/combination/list/formItem", new createFormItem());
        digester.addSetProperties("page/form/combination/list/formItem");
        digester.addRule("page/form/combination/list/formItem/attribute", new addItemAttributeRule());
        digester.addRule("page/form/combination/list/formItem/itemValue", new setItemValue());
        digester.addSetNext("page/form/combination/list/formItem", "addCombinationFormItem", "com.bolt.core.view.components.FormItem");
        digester.addSetNext("page/form/combination", "addFormItems", "com.bolt.core.view.components.FormItem");


        digester.addRule("page/form/fieldset", new createFieldset());
        digester.addSetProperties("page/form/fieldset");
        digester.addRule("page/form/fieldset/formItem", new createFormItem());
        digester.addSetProperties("page/form/fieldset/formItem");
        digester.addRule("page/form/fieldset/formItem/attribute", new addItemAttributeRule());
        digester.addRule("page/form/fieldset/formItem/itemValue", new setItemValue());


        digester.addObjectCreate("page/form/fieldset/combination", "com.bolt.core.view.components.CombinationFormItem");
        digester.addSetProperties("page/form/fieldset/combination");
        digester.addRule("page/form/fieldset/combination/list/formItem", new createFormItem());
        digester.addSetProperties("page/form/fieldset/combination/list/formItem");
        digester.addRule("page/form/fieldset/combination/list/formItem/attribute", new addItemAttributeRule());
        digester.addRule("page/form/fieldset/combination/list/formItem/itemValue", new setItemValue());
        digester.addSetNext("page/form/fieldset/combination/list/formItem", "addCombinationFormItem", "com.bolt.core.view.components.FormItem");
        digester.addSetNext("page/form/fieldset/combination", "addFieldsetItems", "com.bolt.core.view.components.FormItem");

        digester.addSetNext("page/form/fieldset/formItem", "addFieldsetItems", "com.bolt.core.view.components.FormItem");
        digester.addSetNext("page/form/fieldset", "addFormItems", "com.bolt.core.view.components.FormItem");


        digester.addObjectCreate("page/table", "com.bolt.core.view.components.Table", "className");
        digester.addSetProperties("page/table");
        digester.addSetNext("page/table", "addTable", "com.bolt.core.view.components.Table");
        digester.addObjectCreate("page/table/head", "com.bolt.core.view.components.TableHead", "className");
        digester.addSetProperties("page/table/head");
        digester.addRule("page/table/head", new putTableHeadStringTemplate());
        digester.addSetNext("page/table/head", "addHead", "com.bolt.core.view.components.TableHead");

    }

    final class createForm extends Rule {
        @Override
        public void begin(String namespace, String name, Attributes attributes) throws Exception {
            Form form  = new Form();
            digester.push(form);
        }
        @Override
        public void end(String namespace, String name) throws Exception {
            digester.pop();
        }
    }

    final class createFormItem extends Rule {
        @Override
        public void begin(String namespace, String name, Attributes attributes) throws Exception {
            String type = attributes.getValue("type");
            FormItem formitem = null;
            if ("multiple".equals(type)) {
                formitem = new MultipleSelect();
            } else if ("select".equals(type) || "multipleSelect".equals(type)) {
                formitem = new SelectBase();
            } else if ("yearSelect".equals(type) || "monthSelect".equals(type)) {
                formitem = new AutoCombox();
            } else if ("combination".equals(type)) {
                formitem = new CombinationFormItem();
            } else if ("radio".equals(type)) {
                formitem = new Radio();
            } else {
                formitem = new FormItem();
            }
            digester.push(formitem);
        }

        @Override
        public void end(String namespace, String name) throws Exception {
            digester.pop();
        }
    }

    final class createFieldset extends Rule {
        @Override
        public void begin(String namespace, String name, Attributes attributes) throws Exception {
            FieldSet formitem = new FieldSet();
            Form form = (Form) digester.peek();
            formitem.setColumn(form.getColumn());
            digester.push(formitem);
        }

        @Override
        public void end(String namespace, String name) throws Exception {
            digester.pop();
        }

    }

    final class setValidateRule extends Rule {
        @Override
        public void begin(String namespace, String name, Attributes attributes) throws Exception {
            ValidatorRule item = (ValidatorRule) digester.peek();
            String value = attributes.getValue("value");
            String[] vals = StrUtil.split(value, "|");
            for (int i = 0; i < vals.length; i++) {
                item.handleValidatorValue(vals[i]);
            }
            item.setId(attributes.getValue("id"));
            String message = StrUtil.emptyIf(attributes.getValue("message"), "");
            String[] arrymessage = StrUtil.split(message, "|");
            ;
            for (int i = 0; i < arrymessage.length; i++) {
                item.addMessage(arrymessage[i]);
            }

        }
    }

    final class setItemValue extends Rule {
        @Override
        public void begin(String namespace, String name, Attributes attributes) throws Exception {
            FormItem item = (FormItem) digester.peek();
            String value = attributes.getValue("value");
            String prefix = StrUtil.sub(value, 0, value.indexOf(":"));
            String context = StrUtil.sub(value, value.indexOf(":") + 1, value.length());
            if (StrUtil.equalsIgnoreCase("list", prefix)) {
                item.addParameter("itemValue", doList(context));
            } else if (StrUtil.equalsIgnoreCase("method", prefix)) {
                doMethod(item, context);
            } else {
                item.addParameter("itemValue", context);
            }
        }

        private void doMethod(FormItem item, String context) {
            final StringTokenizer parser = new StringTokenizer(context, "|", false);
            while (parser.hasMoreTokens()) {
                String token = StrUtil.trimToEmpty(parser.nextToken());
                String[] keys = token.split("=");
                item.addParameter(keys[0], keys[1]);
            }
        }

        private Map <String, String> doList(String context) {
            Map <String, String> valus = new LinkedHashMap <String, String>();
            final StringTokenizer parser = new StringTokenizer(context, "|", false);
            while (parser.hasMoreTokens()) {
                String token = StrUtil.trimToEmpty(parser.nextToken());
                String[] keys = token.split("=");
                valus.put(keys[0], keys[1]);
            }
            return valus;
        }
    }

    final class addItemAttributeRule extends Rule {
        @Override
        public void begin(String namespace, String name, Attributes attributes) throws Exception {
            String text = attributes.getValue("value");
            if (text != null) {
                FormItem item = (FormItem) digester.peek();
                ConfigUtils.parserConfigText(item, text);
            }
        }

        public addItemAttributeRule() {
            super();
        }
    }

    final class putTableHeadStringTemplate extends Rule {

        @Override
        public void body(String namespace, String name, String text) throws Exception {
            if (text != null) {
                TableHead heand = (TableHead) digester.peek();
                heand.setBody(text);
            }
        }

    }
}
